#pragma once

#include <string>
#include <functional>
#include <system_error>
#include <optional>
#include "helper/sqlite/shortcut/DBWrapper.h"
#include "helper/sqlite/QueryResult.h"

namespace helper {
namespace sqlite {
  class IDB;
  class Statement;
  class Value;
}//namespace sqlite
}//namespace helper

namespace helper {
namespace sqlite {
namespace shortcut {

class Query : public DBWrapper{
public:

  explicit Query(IDB & db) ;
  ~Query() override ;

  using fbind_type = std::function<std::error_code (Statement & stmt)>;
  using fetch_type = std::function<std::error_code (QueryResult & result)>;
  std::error_code query(const std::string & sql, const fetch_type & ffetch, const fbind_type &  fbind = fbind_type()) const;

  using fvisit_row_type = std::function<std::error_code(int, helper::sqlite::QueryResult &)>;
  std::error_code query(const std::string & sql, const fvisit_row_type & fvisit_row, const fbind_type & fbind = fbind_type()) const;

  using fvisit_value_type = std::function<std::error_code(int , int, std::optional<helper::sqlite::Value> &&, helper::sqlite::QueryResult & )>;
  std::error_code query(const std::string & sql, const fvisit_value_type & fvisit_value, const fbind_type & fbind = fbind_type()) const;

};


}//namespace shortcut
}//namespace sqlite
}//namespace helper
